package com.ebt.m.customer.ui;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.ebt.m.AppContext;
import com.ebt.m.AppInitService;
import com.ebt.m.R;
import com.ebt.m.commons.buscomponent.listview.pulltorefresh.PullToRefreshView;
import com.ebt.m.commons.utils.NetUtils;
import com.ebt.m.commons.utils.RxUtil;
import com.ebt.m.commons.widgets.BaseRxFragment;
import com.ebt.m.customer.CustomerUtil;
import com.ebt.m.customer.constant.CustomerConstant;
import com.ebt.m.customer.event.EventACustomerChoosen;
import com.ebt.m.customer.event.EventCustomerChooseAdded;
import com.ebt.m.customer.event.EventCustomerChooseSearch;
import com.ebt.m.customer.event.EventCustomerListRefresh;
import com.ebt.m.customer.model.CustomerModelNew;
import com.ebt.m.customer.net.json.CustomerListJson;
import com.ebt.m.customer.util.CustomerConvertUtil;
import com.ebt.m.customer.util.ToastUtil;
import com.ebt.m.customer.view.CustomerItemChooseView;
import com.ebt.m.customer.view.CustomerItemMainActiveView;
import com.ebt.m.customer.view.ICustomizedViewNew;
import com.ebt.m.customer.view.VerticalStraightTextView;
import com.ebt.m.data.rxModel.api.EBTAPI;
import com.ebt.m.utils.UIHelper;
import com.ebt.m.widget.EBTProgress;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class FragmentCustomerChoose extends BaseRxFragment implements CustomerItemChooseView.OnChooseListener, View.OnClickListener {

    @Override
    public void onChoose(CustomerModelNew customerModelNew) {
        if (mCustomerChooseListener != null) {
            mCustomerChooseListener.onPick(customerModelNew);
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.no_net_container:
                onSwipeRefresh();
                break;
            case R.id.net_slow_container:
                onSwipeRefresh();
                break;
            case R.id.load_refresh:
                onSwipeRefresh();
                break;
            case R.id.load_refresh_net:
                onSwipeRefresh();
                break;
        }
    }

    public interface CustomerChooseListener {
        void onPick(CustomerModelNew customer);

        void onCancel();
    }

    private CustomerChooseListener mCustomerChooseListener;

    public void setChooseListener(CustomerChooseListener listener) {
        mCustomerChooseListener = listener;
    }

    private TextView mToastView;
    private RecyclerView mRecyclerView;
    private PullToRefreshView mSwipeView;
    private VerticalStraightTextView mAlphabetView;

    private LinearLayoutManager mLinearLayoutManager;
    private static final int PRE_EXTRA_SIZE = 1;
    private ArrayList<CustomerModelNew> mCustomerModelNews = new ArrayList();
    private ArrayList<CustomerModelNew> mCustomerModelNewsAll = new ArrayList();
    private ArrayList<CustomerModelNew> mCustomerModelNewsSearch = new ArrayList();
    private HashMap<Integer, Integer> mSectionToPosition = new HashMap();
    private int mModelSize;

    private AdapterForRecyclerView mAdapter;
    private EBTProgress progress;

    private View mEmptyView;
    private ImageView mEmptyImageView;
    private TextView mEmptyTextView;
    private View noNetContainer;
    private View netSlowContainer;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return initViews(inflater);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initValues();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    private View initViews(LayoutInflater inflater) {
        View contentView = inflater.inflate(R.layout.fragment_customer_choose, null);
        progress = (EBTProgress) contentView.findViewById(R.id.progress);
        mEmptyView = contentView.findViewById(R.id.empty_container);
        mEmptyImageView = (ImageView) contentView.findViewById(R.id.iv_empty);
        mEmptyTextView = (TextView) contentView.findViewById(R.id.tv_empty);
        noNetContainer = contentView.findViewById(R.id.no_net_container);
        netSlowContainer = contentView.findViewById(R.id.net_slow_container);
        netSlowContainer = contentView.findViewById(R.id.net_slow_container);
        View view1 = contentView.findViewById(R.id.load_refresh);
        View view2 = contentView.findViewById(R.id.load_refresh_net);

        noNetContainer.setOnClickListener(this);
        netSlowContainer.setOnClickListener(this);
        view1.setOnClickListener(this);
        view2.setOnClickListener(this);
        mSwipeView = (PullToRefreshView) contentView.findViewById(R.id.swipe_view);
        mRecyclerView = (RecyclerView) contentView.findViewById(R.id.recycler_view);
        mToastView = (TextView) contentView.findViewById(R.id.toast_view);
        mAlphabetView = (VerticalStraightTextView) contentView.findViewById(R.id.alphabet_view);

        initSwipeRefreshLayout();
        initRecyclerView();
        return contentView;
    }

    protected void initSwipeRefreshLayout() {
        mSwipeView.setOnRefreshListener(new PullToRefreshView.OnRefreshListener() {
            @Override
            public void onRefresh() {
                onSwipeRefresh();
            }
        });
    }

    private void showProgress() {
        if (progress != null) {
            progress.setVisibility(View.VISIBLE);
        }
    }

    private void hideProgress() {
        if (progress != null) {
            progress.setVisibility(View.GONE);
        }
    }

    private void onSwipeRefresh() {
        refresh(false);
    }

    private void initValues() {
        initViewFactory();
        refresh(true);
    }

    private IViewFactory mFactory;

    private void initViewFactory() {
        if (mFactory == null) {
            mFactory = new IViewFactory() {
                @Override
                public ICustomizedViewNew createView(int type) {   //type就是position
                    if (type == 0) {
                        CustomerItemMainActiveView view = new CustomerItemMainActiveView(getContext(), CustomerUtil.FROM_CHOOSE);
                        return view;
                    } else if (type > 0) {
                        return new CustomerItemChooseView(getContext()).setOnChooseListener(FragmentCustomerChoose.this);
                    }
                    return null;
                }
            };
        }
    }

    private void initRecyclerView() {
        if (mLinearLayoutManager == null) {
            mLinearLayoutManager = new LinearLayoutManager(this.getContext());
        }
        mRecyclerView.setLayoutManager(mLinearLayoutManager);
        mRecyclerView.clearOnScrollListeners();
        mRecyclerView.addOnScrollListener(new ScrollListener());

        mCustomerModelNews.clear();
        mModelSize = mCustomerModelNews.size();
        mSectionToPosition.clear();
        if (mAdapter == null) {
            mAdapter = new AdapterForRecyclerView(mCustomerModelNews);
            mRecyclerView.setAdapter(mAdapter);
        }
    }

    private void refresh(boolean fromInit) {
        if (fromInit) {
            showProgress();
        } else {
            showRefresh();
        }

        if (!AppContext.getCurrentUser().isLogined()) {
            ToastUtil.showToast("请先登录");
            hideRefresh();
            hideProgress();
            return;
        }
        EBTAPI ebtapi = AppInitService.getEbtApi();
        ebtapi.getCustomerList().compose(RxUtil.rxTransformer(this)).subscribe(getCustomerListSubscriber());
    }

    private Observer<CustomerListJson> getCustomerListSubscriber() {
        return new Observer<CustomerListJson>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onComplete() {
                hideRefresh();
                hideProgress();
            }

            @Override
            public void onError(Throwable e) {
                UIHelper.makeToast(getContext(), getString(R.string.network_fail));
                if (NetUtils.isNetworkAvailable(getContext())) {
                    showEmpty(false, false, false, true);
                } else {
                    showEmpty(false, false, true, false);
                }
                hideRefresh();
                hideProgress();
            }

            @Override
            public void onNext(CustomerListJson customerListJson) {
                if (customerListJson == null || customerListJson.error != null) {
                    showEmpty(false, false, false, true);
                } else if (customerListJson.data == null) {
                    showEmpty(true, false, false, false);
                } else {
                    showCustomerList(customerListJson);
                }
            }
        };
    }

    protected void hideRefresh() {
        if (mSwipeView != null && mSwipeView.isRefreshing()) {
            mSwipeView.setRefreshing(false);
        }
    }

    protected void showRefresh() {
        if (mSwipeView != null && !mSwipeView.isRefreshing()) {
            mSwipeView.setRefreshing(true);
        }
    }

    class ScrollListener extends RecyclerView.OnScrollListener {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (mFlagMove) {
                mFlagMove = false;
                int n = mTargetPosition - mLinearLayoutManager.findFirstVisibleItemPosition();
                if (0 <= n && n < mRecyclerView.getChildCount()) {
                    int top = mRecyclerView.getChildAt(n).getTop();
                    mRecyclerView.scrollBy(0, top);
                }
            }
        }
    }

    class AdapterForRecyclerView extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private List<CustomerModelNew> customerModelMultis;

        public AdapterForRecyclerView(List<CustomerModelNew> customerModelMultis) {
            this.customerModelMultis = customerModelMultis;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new AdapterForRecyclerView.CustomerMainViewHolder(mFactory.createView(viewType).getView());
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ICustomizedViewNew iCustomizedView = (ICustomizedViewNew) holder.itemView;
            if (position < PRE_EXTRA_SIZE) {

            } else {

                iCustomizedView.update(customerModelMultis.get(position - PRE_EXTRA_SIZE));
                int section = getSectionForPosition(position - PRE_EXTRA_SIZE);
                int firstPosition = getPositionForSection(section);
                if (firstPosition + PRE_EXTRA_SIZE == position) {
//                    iCustomizedView.showSortTitle(customerModelMultis.get(position - PRE_EXTRA_SIZE).sortKeyChar);
                    if (section < 0) {
                        section = 0;
                    } else if (section >= CustomerConstant.Sort.CHARS_ALPHA_SIZE) {
                        section = CustomerConstant.Sort.CHARS_ALPHA_SIZE - 1;
                    }
                    iCustomizedView.showSortTitle(String.valueOf(CustomerConstant.Sort.CHARS_ALPHA[section]));
                } else {
                    iCustomizedView.showSortTitle(null);
                    //隐藏title
                }
            }
        }

        @Override
        public int getItemCount() {
            return customerModelMultis.size() + PRE_EXTRA_SIZE;
        }

        @Override
        public int getItemViewType(int position) {
            if (position < PRE_EXTRA_SIZE) {
                return 0;
            }
            return 1;
        }

        class CustomerMainViewHolder extends RecyclerView.ViewHolder {
            public CustomerMainViewHolder(View itemView) {
                super(itemView);
            }
        }
    }

    public int getPositionForSection(int section) {

        if (section >= 27) {
            return CustomerConstant.Sort.CHARS_ALPHA_SIZE - 1;
        }
        if (section < 0) {
            return 0;
        }

        Integer p = mSectionToPosition.get(section);
        if (p != null) {
            return p;
        }

        char c = CustomerConstant.Sort.CHARS_ALPHA[section];
        int size = mModelSize;

        for (int i = 0; i < size; i++) {
            if (mCustomerModelNews.get(i).sortKeyChar.charAt(0) >= c) {
                mSectionToPosition.put(section, i);
                return i;
            }
        }
        return -1;
    }

    public int getSectionForPosition(int position) {
        if (position >= mModelSize) {
            return -1;
        }

        char c = mCustomerModelNews.get(position).sortKeyChar.charAt(0);//IndexOutOfBoundsException
        for (int i = 0; i < CustomerConstant.Sort.CHARS_ALPHA_SIZE; i++) {
            if (c == CustomerConstant.Sort.CHARS_ALPHA[i]) {
                return i;
            }
        }
        return -1;
    }

    //scroll相关数据
    private int mTargetPosition = -1;
    private boolean mFlagMove = false;

    public interface IViewFactory {
        ICustomizedViewNew createView(int type);
    }

    private void setAlphabetListener(boolean hasData) {
        if (hasData) {
            mAlphabetView.setOnTouchedCharListener(new VerticalStraightTextView.OnTouchedCharListener() {

                @Override
                public void onTouchedCharReleased(String releasedString, int releasedIndex) {
                }

                @Override
                public void onTouchedCharChanged(String releasedString, int releasedIndex, String pickedString, int pickedIndex) {
                }

                @Override
                public void onTouchedCharPicked(String pickedString, int pickedIndex) {
                    String sectionLetterActionDown = String.valueOf(CustomerConstant.Sort.CHARS_ALPHA[pickedIndex]);
                    mToastView.setText(sectionLetterActionDown);
                    mToastView.setVisibility(View.VISIBLE);
                    int positionActionDown = getPositionForSection(pickedIndex);
                    setSelection(positionActionDown);
                }

                @Override
                public void onTouchedCharReleasedFinally(String releasedString, int releasedIndex) {
                    mToastView.setVisibility(View.GONE);
                }
            });

            if (mAlphabetView.getVisibility() != View.VISIBLE) {
                mAlphabetView.setVisibility(View.VISIBLE);
            }
        } else {
            mAlphabetView.setOnTouchedCharListener(null);
            if (mAlphabetView.getVisibility() != View.GONE) {
                mAlphabetView.setVisibility(View.GONE);
            }
        }
    }

    public void setSelection(int position) {
        moveToPosition(position);
    }

    private void moveToPosition(int position) {
        mTargetPosition = position;
        int firstItem = mLinearLayoutManager.findFirstVisibleItemPosition();
        int lastItem = mLinearLayoutManager.findLastVisibleItemPosition();
        if (position <= firstItem) {
            mRecyclerView.scrollToPosition(position);
        } else if (position <= lastItem) {
            int top = mRecyclerView.getChildAt(position - firstItem).getTop();
            mRecyclerView.scrollBy(0, top);
        } else {
            mRecyclerView.scrollToPosition(position);
            mFlagMove = true;
        }
    }

    private void showCustomerList(CustomerListJson customerListJson) {
        List<CustomerModelNew> list = new ArrayList<>();
        if (customerListJson.data != null) {
            list = CustomerConvertUtil.convertCustomerListToCustomerModelNewList(customerListJson.data);
        }
        mCustomerModelNewsAll.clear();
        mCustomerModelNewsAll.addAll(list);
        showAllData(false);
    }

    private void showAllData(boolean isSearch) {
        mCustomerModelNews.clear();
        mCustomerModelNews.addAll(mCustomerModelNewsAll);
        mModelSize = mCustomerModelNews.size();
        mSectionToPosition.clear();
        if (mAdapter == null) {
            mAdapter = new AdapterForRecyclerView(mCustomerModelNews);
            mRecyclerView.setAdapter(mAdapter);
        } else {
            mAdapter.notifyDataSetChanged();
        }
        setAlphabetListener(mCustomerModelNews.size() != 0);
        showEmpty(mCustomerModelNews.size() == 0, isSearch, false, false);
    }

    private void showSearchData(String keywords) {
        if (TextUtils.isEmpty(keywords)) {
            showAllData(true);
            return;
        }

        mCustomerModelNewsSearch.clear();
        Observable.create(new ObservableOnSubscribe<ArrayList<CustomerModelNew>>() {
            @Override
            public void subscribe(ObservableEmitter<ArrayList<CustomerModelNew>> observableEmitter) throws Exception {
                for (CustomerModelNew item : mCustomerModelNewsAll) {
                    if (!TextUtils.isEmpty(item.name) && item.name.contains(keywords)) {
                        mCustomerModelNewsSearch.add(item);
                    }
                }
                observableEmitter.onNext(mCustomerModelNewsSearch);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io())
                .subscribe(new Observer<ArrayList<CustomerModelNew>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onComplete() {
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onNext(ArrayList<CustomerModelNew> b) {
                        mCustomerModelNews.clear();
                        mCustomerModelNews.addAll(mCustomerModelNewsSearch);
                        mModelSize = mCustomerModelNews.size();
                        mSectionToPosition.clear();
                        if (mAdapter == null) {
                            mAdapter = new AdapterForRecyclerView(mCustomerModelNews);
                            mRecyclerView.setAdapter(mAdapter);
                        } else {
                            mAdapter.notifyDataSetChanged();
                        }
                        if (mCustomerModelNews == null || mCustomerModelNews.size() == 0) {
                            showEmpty(true, true, false, false);
                            setAlphabetListener(false);
                        } else {
                            hideEmptyUI();
                            setAlphabetListener(true);
                        }
                    }
                });
    }

    /**
     * 空图和错误图片显示逻辑
     *
     * @param empty
     * @param no_net
     * @param net_slow
     */
    public void showEmpty(boolean empty, boolean isSearch, boolean no_net, boolean net_slow) {
        if (empty) {
            if (isSearch) {
                mEmptyTextView.setText("没有搜索到客户");
                mEmptyImageView.setImageResource(R.drawable.ic_empty_search);
            } else {
                mEmptyTextView.setText("没有客户哦");
                mEmptyImageView.setImageResource(R.drawable.ic_no_customer);
            }
            mEmptyView.setVisibility(View.VISIBLE);
        } else {
            mEmptyView.setVisibility(View.GONE);
        }
        noNetContainer.setVisibility(no_net ? View.VISIBLE : View.GONE);
        netSlowContainer.setVisibility(net_slow ? View.VISIBLE : View.GONE);
    }

    private void hideEmptyUI() {
        mEmptyView.setVisibility(View.GONE);
        mRecyclerView.setVisibility(View.VISIBLE);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventCustomerListRefresh event) {
        refresh(false);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventCustomerChooseAdded event) {
        if (event != null && event.modelNew != null) {
            if (mCustomerChooseListener != null) {
                mCustomerChooseListener.onPick(event.modelNew);
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventACustomerChoosen event) {
        if (event != null && event.customerActive != null) {
            CustomerModelNew customerModelNew = CustomerConvertUtil.convertCustomerActiveToCustomerModelNew(event.customerActive);
            if (mCustomerChooseListener != null) {
                mCustomerChooseListener.onPick(customerModelNew);
            }
            return;
        }
        if (event != null && event.customerModelNew != null) {
            if (mCustomerChooseListener != null) {
                mCustomerChooseListener.onPick(event.customerModelNew);
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventCustomerChooseSearch event) {
        if (event == null) {
            return;
        }
        if (TextUtils.isEmpty(event.keywords)) {
            showAllData(true);
            showAlphabetView(true);
        } else {
            showSearchData(event.keywords);
            showAlphabetView(false);
        }
    }

    private void showAlphabetView(boolean show) {
        if (mAlphabetView == null) {
            return;
        }
        if (show) {
            if (mAlphabetView.getVisibility() != View.VISIBLE) {
                mAlphabetView.setVisibility(View.VISIBLE);
            }
        } else {
            if (mAlphabetView.getVisibility() != View.GONE) {
                mAlphabetView.setVisibility(View.GONE);
            }
        }
    }
}